package manager

import activity.MainActivity
import ext.calcCrc
import ext.log
import ext.subArray
import protocol.BaseProtocol
import serialport.DeliverPortManager

object OTAManager {
    private var mUpdatePackage: ByteArray = byteArrayOf()
    private var mAlreadySize = 0
    private var mPackageId = 0
    var isUpdate = false

    fun start(pack: ByteArray) {
        isUpdate = true
        mUpdatePackage = pack
        mAlreadySize = 0
        mPackageId = 0
        log("开始升级下位机:${pack.size}")
        notifyPackageSize(mUpdatePackage.size)
    }

    /**
     * 发送升级通知
     */
    private fun notifyPackageSize(size: Int) {
        val buf = BaseProtocol(0x30)
            .append7Int4(size)
            .build()
        DeliverPortManager.Instance.write(buf)
    }

    /**
     * 升级通知发送成功回调
     */
    fun onUpdateReady(state: Int) {
        if (state == 0) {
            nextPackage()
            return
        }
        log("升级错误")
        isUpdate = false
    }

    /**
     * 发送下一个数据包
     */
    fun nextPackage() {
        val rel = mUpdatePackage.size - mAlreadySize
        if (rel <= 0) {
            onUpdateComplete()
            return
        }
        val size = if (rel >= 128) {
            128
        } else {
            rel
        }
        val pack = mUpdatePackage.subArray(mAlreadySize, size)
        val buf = BaseProtocol(0x40)
            .append7Int2(mPackageId)
            .appendAll(pack)
            .build()
        DeliverPortManager.Instance.write(buf)
        mPackageId++
        mAlreadySize += size
    }

    /**
     * 数据包接收成功回调
     */
    fun onPackageReady(state: Int) {
        if (state == 0) {
            nextPackage()
            return
        }
        log("升级过程中异常")
        isUpdate = false
    }

    /**
     * 数据包发送完毕回调
     */
    private fun onUpdateComplete() {
        val crc = mUpdatePackage.calcCrc()
        val buf = BaseProtocol(0x50)
            .append7Int4(crc)
            .build()
        DeliverPortManager.Instance.write(buf)
    }

    /**
     * 升级完成回调
     */
    fun onCompleteNotify(state: Int) {
        if (state == 0) {
            log("升级成功")
            return
        }
        log("升级失败CRC校验出错")
        isUpdate = false
        return
    }

    class DownTask(val url: String) : Runnable {
        override fun run() {
            try {
                val pack = HttpRequestManager.downLoadOTA(url)
                if (pack.size > 1024 * 4 && MainActivity.isShow && (!AppManager.isBusy)) {
                    OTAManager.start(pack)
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
}